package com.huaxindata.im.main.chat.mp3recorder.audio.receiver;

import android.annotation.TargetApi;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.os.Build;
import android.util.Log;

import com.huaxindata.im.main.chat.mp3recorder.audio.AudioCodec;
import com.huaxindata.im.main.chat.mp3recorder.audio.AudioConfig;
import com.huaxindata.im.main.chat.mp3recorder.audio.data.AudioData;
import com.huaxindata.im.main.chat.mp3recorder.netnat.NetNatConfig;

import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class AudioPlayer implements Runnable {
    String LOG = "AudioPlayer ";
    private static AudioPlayer player;

    private List<AudioData> dataList = null;
    private boolean isPlaying = false;

    private AudioTrack audioTrack;

    private AudioPlayer() {
        dataList = Collections.synchronizedList(new LinkedList<AudioData>());
    }

    public static AudioPlayer getInstance() {
        if (player == null) {
            player = new AudioPlayer();
        }
        return player;
    }

    public void addData(byte[] encode, int size) {
        AudioData encodeData = new AudioData();
        encodeData.setSize(size);
        byte[] tempData = new byte[size];
        System.arraycopy(encode, 0, tempData, 0, size);
        encodeData.setData(tempData);
        dataList.add(encodeData);
    }

    /*
     * init Player parameters
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private boolean initAudioTrack() {
        int bufferSize = AudioRecord.getMinBufferSize(AudioConfig.SAMPLERATE,
                AudioConfig.PLAYER_CHANNEL_CONFIG,
                AudioConfig.AUDIO_FORMAT);
        if (bufferSize < 0) {
            Log.e(LOG, LOG + "initialize error!");
            return false;
        }
        Log.i(LOG, "Player初始化的 buffersize是 " + bufferSize);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                AudioConfig.SAMPLERATE, AudioConfig.PLAYER_CHANNEL_CONFIG,
                AudioConfig.AUDIO_FORMAT, bufferSize, AudioTrack.MODE_STREAM);
        // set volume:设置播放音量
        audioTrack.setVolume(1.0f);
        audioTrack.play();
        return true;
    }

    private void playFromList() throws IOException {
        short[] decodedData = new short[1024];
        int num;
        boolean magicVaild;
        int sqen;
        int n;
        boolean test = true;
        AudioData play;

        AudioCodec.initCodec(30);

        while (isPlaying) {
            if (dataList.size() > 0) {
                play = dataList.remove(0);
                byte[] buffer = play.getData();
                if (test) {
                    num = AudioCodec.decode(buffer, decodedData, play.getSize());
                } else {
                    magicVaild = true;
                    for (int i = 0; i < NetNatConfig.MAGIC.length; i++) {
                        if (buffer[i] != NetNatConfig.MAGIC[i]) {
                            System.err.println("Invalid message!" + String.valueOf(buffer));
                            magicVaild = false;
                            continue;
                        }
                    }
                    if (!magicVaild) {
                        continue;
                    }
                    // 获取类型
                    int type = buffer[6];
                    if (type == NetNatConfig.Type.VOICE_DATA) {
                        sqen = NetNatConfig.getInt(buffer, 7, 9);
                        n = buffer[9];
                        byte[] recv = new byte[n];
                        for (int i = 0; i < n; i++) {
                            recv[i] = buffer[10 + i];
                        }
                        // 每接收一个UDP包，就交给解码器，等待解码
                        num = AudioCodec.decode(recv, decodedData, n);
                    } else {
                        num = 0;
                    }
                }
                if (num > 0) {
                    //Log.e(LOG, "解码一次 " + packet.getLength() + " 解码后的长度 " + num);
                    // add decoded audio to player
                    //解码成功后,将要播放的pcm数据放入回音消除playback中
                    short[] tempData = new short[num];
                    System.arraycopy(decodedData, 0, tempData, 0, num);
                    AudioCodec.playback(tempData);
                    audioTrack.write(tempData, 0, num);
                }
            }
            //控制每20ms播放一帧
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
            }
        }
    }

    public void startPlaying() {
        if (isPlaying) {
            Log.e(LOG, "验证播放器是否打开" + isPlaying);
            return;
        }
        new Thread(this).start();
    }

    public void run() {
        android.os.Process
                .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

        this.isPlaying = true;
        if (!initAudioTrack()) {
            Log.i(LOG, "播放器初始化失败");
            return;
        }
        Log.e(LOG, "开始播放");
        try {
            playFromList();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // while (isPlaying) {
        // if (dataList.size() > 0) {
        // playFromList();
        // } else {
        //
        // }
        // }
        if (this.audioTrack != null) {
            if (this.audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
                this.audioTrack.stop();
                this.audioTrack.release();
            }
        }
        Log.d(LOG, LOG + "end playing");
    }

    public void stopPlaying() {
        this.isPlaying = false;
    }
}
